home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / graphics / a-g / beyondthedark / developer / source / spline / spline.c < prev   
Encoding:
C/C++ Source or Header  |  1995-12-21  |  8.5 KB  |  365 lines

  1. /* spline Library */
  2.  
  3. #include <exec/memory.h>
  4. #include <exec/execbase.h>
  5. #include <libraries/iffparse.h>
  6. #include <utility/tagitem.h>
  7. #include <graphics/gfxbase.h>
  8. #include <intuition/intuitionbase.h>
  9.  
  10. #include <clib/macros.h>
  11.  
  12. #define __USE_SYSBASE 42
  13.  
  14. #include <proto/exec.h>
  15. #include <proto/graphics.h>
  16. #include <proto/intuition.h>
  17. #include <proto/utility.h>
  18.  
  19. #include <math.h>
  20.  
  21. #include <BTD.h>
  22.  
  23. struct IntuitionBase *IntuitionBase;
  24. struct GfxBase *GfxBase;
  25. struct Library *UtilityBase;
  26.  
  27. /* #define DEBUG YES */
  28.  
  29. #ifdef DEBUG 
  30.  
  31. void KPrintF(char *,...);
  32.  
  33. #define DEBUG_PRINTF(a,b)  KPrintF(a,b);
  34. #define DEBUG_PRINT(a)     KPrintF(a)
  35. #else
  36. #define DEBUG_PRINTF(a,b)
  37. #define DEBUG_PRINT(a)
  38. #endif
  39.  
  40.  
  41. #define QTAG(o) (BTD_Client+(o))
  42.  
  43. #define SP_Seconds QTAG(0)
  44. #define SP_Colors  QTAG(2)
  45.  
  46. #define MAX_SECONDS 2048L /* seconds until a new graphic is plotted */
  47.  
  48. #define DEF_SECONDS 128L
  49.  
  50. #define DEF_COLORS 8L
  51. #define MAX_COLORS 255L
  52.  
  53. struct BTDInteger splineIntParams[] =
  54.  {
  55.   SP_Seconds,"Patternchange",BTDPT_INTEGER,DEF_SECONDS,1L,MAX_SECONDS,TRUE,
  56.   SP_Colors,"Colors",BTDPT_INTEGER,DEF_COLORS,4L,MAX_COLORS,TRUE
  57.  };
  58.  
  59. struct BTDNode *splineParams[] = 
  60.  {
  61.   &splineIntParams[0].BI_Node,
  62.   &splineIntParams[1].BI_Node,NULL
  63.  };
  64.  
  65. struct BTDInfo splineInfo =
  66.  {
  67.   BTDI_Revision,MAKE_ID('S','P','L','I'),
  68.   "Splinefun","Yet another standard modul","Markus Illenseer 1995",
  69.   splineParams
  70.  };
  71.  
  72. char MyBlankerName[] = "spline.btd";
  73. char MyBlankerID[]   = "Spline Fun Blanker V" VERSION "." REVISION " for BTD";
  74.  
  75.  
  76. LONG MyBlankerLibInit(void)
  77.  
  78. {
  79.  if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
  80.   {
  81.    if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
  82.     {
  83.      if (UtilityBase=OpenLibrary("utility.library",37L)) return TRUE;
  84.  
  85.      CloseLibrary (&IntuitionBase->LibNode);
  86.     }
  87.    CloseLibrary (&GfxBase->LibNode);
  88.   }
  89.  return FALSE;
  90. }
  91.  
  92. void MyBlankerLibFree(void)
  93.  
  94. {
  95.  CloseLibrary (UtilityBase);
  96.  CloseLibrary (&IntuitionBase->LibNode);
  97.  CloseLibrary (&GfxBase->LibNode);
  98. }
  99.  
  100.  
  101. typedef struct {
  102.   LONG  x,y;
  103. } point;
  104.  
  105. #define MAXPOINTS 99
  106. #define MAX_DELTA 3
  107. #define MAX_SPLINES 2048
  108.  
  109. #define SPLINE_THRESH 5
  110.  
  111. struct splineStruct
  112.  {
  113.   struct BTDDrawInfo *BTDDrawInfo;
  114.   LONG   hs_RandN,hs_RandF,hs_RandI;
  115.   int colors;
  116.   int        width;
  117.   int        height;
  118.   int        color;
  119.   int        points;
  120.   int         generation;
  121.   int x[MAXPOINTS], y[MAXPOINTS], dx[MAXPOINTS], dy[MAXPOINTS];
  122.   int ncolors;
  123.   int seconds;
  124.  };
  125.  
  126.  
  127. struct BTDInfo *QueryMyBlanker(void)
  128.  
  129. {
  130.  return &splineInfo;
  131. }
  132.  
  133.  
  134. void __regargs InitRandom(struct splineStruct *SP,ULONG Instance)
  135.  
  136. {
  137.  ULONG Time[2];
  138.  
  139.  CurrentTime (&Time[0],&Time[1]);
  140.  SP->hs_RandN=(LONG)Time[0];
  141.  if (Time[1]<1024L) Time[1]|=1;
  142.  else Time[1]>>=10;
  143.  Time[1]^=Instance;
  144.  
  145.  SP->hs_RandF=4*Time[1]+1;
  146.  SP->hs_RandI=2*Time[1]+1;
  147. }
  148.  
  149. WORD __regargs Random(struct splineStruct *SP,WORD Max)
  150.  
  151. {
  152.  SP->hs_RandN=SP->hs_RandF*SP->hs_RandN+SP->hs_RandI;
  153.  if (SP->hs_RandN<0L) SP->hs_RandN=-SP->hs_RandN;
  154.  
  155.  return (WORD)(SP->hs_RandN%Max);
  156. }
  157.  
  158.  
  159. #define FindTagData(l,t,d) GetTagData((t),(d),(l))
  160. /* rainbow colors */
  161.  
  162. #define NUM_RAINBOW_COLORS 6
  163.  
  164. UBYTE RBRed[NUM_RAINBOW_COLORS+1]   = {0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF};
  165. UBYTE RBGreen[NUM_RAINBOW_COLORS+1] = {0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00};
  166. UBYTE RBBlue[NUM_RAINBOW_COLORS+1]  = {0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00};
  167.  
  168. /* spline routine. */
  169.  
  170. struct splineStruct *InitMyBlanker(struct TagItem *TagList)
  171. {
  172.  LONG i;
  173.  struct splineStruct *SP;
  174.  struct BTDDrawInfo *BTDDrawInfo;
  175.  ULONG *Error,Dummy,Index,Instance;
  176.  
  177.  if ((BTDDrawInfo=(struct BTDDrawInfo *)
  178.                    FindTagData(TagList,BTD_DrawInfo,NULL))==NULL) return NULL;
  179.  Error=(LONG *)FindTagData(TagList,BTD_Error,(ULONG)&Dummy);
  180.  if ((SP=AllocVec(sizeof(struct splineStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  181.   {
  182.    *Error=BTDERR_Memory;
  183.    return NULL;
  184.   }
  185.  
  186.  SP->seconds=FindTagData(TagList,SP_Seconds,DEF_SECONDS);
  187.  SP->ncolors=FindTagData(TagList,SP_Colors,DEF_COLORS);
  188.  Instance=FindTagData(TagList,BTD_Instance,0L);
  189.  
  190.  InitRandom(SP,Instance);
  191.  
  192.  SP->BTDDrawInfo=BTDDrawInfo;
  193.  SP->width=BTDDrawInfo->BDI_Width;
  194.  SP->height=BTDDrawInfo->BDI_Height;
  195.  
  196.  SP->points = Random(SP,5-3) + 3;
  197.  SP->generation = 0;
  198.  
  199.     for ( i = 0; i < SP->points; ++i )
  200.         {
  201.         SP->x[i] = Random(SP,SP->width);
  202.         SP->y[i] = Random(SP,SP->height);
  203.         SP->dx[i] = Random(SP,MAX_DELTA * 2 ) - MAX_DELTA;
  204.         if ( SP->dx[i] <= 0 ) --SP->dx[i];
  205.         SP->dy[i] = Random(SP,MAX_DELTA * 2 ) - MAX_DELTA;
  206.         if ( SP->dy[i] <= 0 ) --SP->dy[i];
  207.         }
  208.     
  209.     SP->color = 0;
  210.  
  211.  
  212.  if (SP->ncolors>NUM_RAINBOW_COLORS)
  213.   {
  214.    LONG ColNum,Col,RBCol;
  215.    UBYTE *Red,*Green,*Blue,*Changed;
  216.  
  217.    Red=BTDDrawInfo->BDI_Red;
  218.    Green=BTDDrawInfo->BDI_Green;
  219.    Blue=BTDDrawInfo->BDI_Blue;
  220.    Changed=BTDDrawInfo->BDI_Changed;
  221.    ColNum=SP->ncolors/NUM_RAINBOW_COLORS+1L;
  222.    Index=0L;
  223.    for (RBCol=0L; RBCol<NUM_RAINBOW_COLORS; RBCol++)
  224.     {
  225.      if (RBCol==(SP->ncolors%NUM_RAINBOW_COLORS)) ColNum--;
  226.  
  227.      for (Col=0L; Col<ColNum; Col++)
  228.       {
  229.        Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[RBCol]+((RBRed[RBCol+1]-RBRed[RBCol])*Col)/ColNum;
  230.        Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[RBCol]+((RBGreen[RBCol+1]-RBGreen[RBCol])*Col)/ColNum;
  231.        Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[RBCol]+((RBBlue[RBCol+1]-RBBlue[RBCol])*Col)/ColNum;
  232.        Changed[BTDDrawInfo->BDI_Pens[Index++]]=TRUE;
  233.       }
  234.     }
  235.   }
  236.  else
  237.   for (Index=0L; Index<SP->ncolors; Index++)
  238.    {
  239.     BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[Index];
  240.     BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[Index];
  241.     BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[Index];
  242.     BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  243.    }
  244.  
  245. DEBUG_PRINT("spline: Init ready\n");
  246.  
  247.  return SP;
  248. }
  249.  
  250. void EndMyBlanker(struct splineStruct *SP)
  251.  
  252. {
  253. DEBUG_PRINT("spline: FreeMem\n");
  254.  FreeVec (SP);
  255. }
  256.  
  257. void initspline(struct splineStruct *SP)
  258. {
  259.  
  260.  int i;
  261.  
  262.  SetRast(SP->BTDDrawInfo->BDI_RPort,0);
  263.  
  264.  SP->points = Random(SP,5-3) + 3;
  265.  SP->generation = 0;
  266.  
  267.     for ( i = 0; i < SP->points; ++i )
  268.         {
  269.         SP->x[i] = Random(SP,SP->width);
  270.         SP->y[i] = Random(SP,SP->height);
  271.         SP->dx[i] = Random(SP,MAX_DELTA * 2 ) - MAX_DELTA;
  272.         if ( SP->dx[i] <= 0 ) --SP->dx[i];
  273.         SP->dy[i] = Random(SP,MAX_DELTA * 2 ) - MAX_DELTA;
  274.         if ( SP->dy[i] <= 0 ) --SP->dy[i];
  275.         }
  276.     
  277.     SP->color = 0;
  278. }
  279.  
  280. void XDrawLine(struct splineStruct *SP, int x0, int y0, int x1, int y1)
  281. {
  282.   Move(SP->BTDDrawInfo->BDI_RPort,x0,y0);
  283.   Draw(SP->BTDDrawInfo->BDI_RPort,x1,y1);
  284. }
  285.  
  286. void XDrawSpline(struct splineStruct *SP, int x0, int y0, int x1, int y1, int x2, int y2)
  287. {
  288.     register int xa, ya, xb, yb, xc, yc, xp, yp;
  289.  
  290.     xa = (x0 + x1) / 2;
  291.     ya = (y0 + y1) / 2;
  292.     xc = (x1 + x2) / 2;
  293.     yc = (y1 + y2) / 2;
  294.     xb = (xa + xc) / 2;
  295.     yb = (ya + yc) / 2;
  296.  
  297.     xp = (x0 + xb) / 2;
  298.     yp = (y0 + yb) / 2;
  299.     if (ABS(xa - xp) + ABS(ya - yp) > SPLINE_THRESH)
  300.         XDrawSpline(SP, x0, y0, xa, ya, xb, yb);
  301.     else
  302.         XDrawLine(SP, x0, y0, xb, yb);
  303.  
  304.     xp = (x2 + xb) / 2;
  305.     yp = (y2 + yb) / 2;
  306.     if (ABS(xc - xp) + ABS(yc - yp) > SPLINE_THRESH)
  307.         XDrawSpline(SP, xb, yb, xc, yc, x2, y2);
  308.     else
  309.         XDrawLine(SP, xb, yb, x2, y2);
  310. }
  311.  
  312. void AnimMyBlanker(struct splineStruct *SP)
  313.  
  314. {
  315.   int i, t, px, py, zx, zy, nx, ny;
  316.  
  317.     /* Move the points. */
  318.     for ( i = 0; i < SP->points; i++ )
  319.         {
  320.         for ( ; ; )
  321.             {
  322.             t = SP->x[i] + SP->dx[i];
  323.             if ( t >= 0 && t < SP->width ) break;
  324.             SP->dx[i] = Random(SP, MAX_DELTA * 2 ) - MAX_DELTA;
  325.             if ( SP->dx[i] <= 0 ) --SP->dx[i];
  326.             }
  327.         SP->x[i] = t;
  328.         for ( ; ; )
  329.             {
  330.             t = SP->y[i] + SP->dy[i];
  331.             if ( t >= 0 && t < SP->height ) break;
  332.             SP->dy[i] = Random(SP,MAX_DELTA * 2 ) - MAX_DELTA;
  333.             if ( SP->dy[i] <= 0 ) --SP->dy[i];
  334.             }
  335.         SP->y[i] = t;
  336.         }
  337.  
  338.     /* Draw the figure. */
  339.     px = zx = ( SP->x[0] + SP->x[SP->points-1] ) / 2;
  340.     py = zy = ( SP->y[0] + SP->y[SP->points-1] ) / 2;
  341.     for ( i = 0; i < SP->points-1; ++i )
  342.         {
  343.         nx = ( SP->x[i+1] + SP->x[i] ) / 2;
  344.         ny = ( SP->y[i+1] + SP->y[i] ) / 2;
  345.         XDrawSpline(SP,px, py, SP->x[i], SP->y[i], nx, ny );
  346.         px = nx;
  347.         py = ny;
  348.         }
  349.     SetAPen(SP->BTDDrawInfo->BDI_RPort,SP->BTDDrawInfo->BDI_Pens[SP->color]);
  350.     if (++SP->color >= SP->ncolors)
  351.       SP->color = 0;
  352.     XDrawSpline(SP, px, py, SP->x[SP->points-1], SP->y[SP->points-1], zx, zy );
  353.  
  354.     if (++SP->generation > SP->seconds) 
  355.      initspline(SP);
  356. }
  357.  
  358. ULONG PenCountMyBlanker(struct TagItem *TagList)
  359.  
  360. {
  361.  ULONG colors;
  362.  colors=FindTagData(TagList,SP_Colors,DEF_COLORS);
  363.  return colors;
  364. }
  365.